home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1995 #5 & #6 / Amiga Plus CD - 1995 - No. 5 and 6.iso / pd / daten / astrolog / src / amiga.c next >
Encoding:
C/C++ Source or Header  |  1995-08-11  |  35.7 KB  |  1,328 lines

  1. /*                                                               -*- C -*-
  2. **  Amiga Graphics for ASTROLOG
  3. **
  4. **  (c)Copyright 1994-95 by Tobias Ferber,  All Rights Reserved
  5. */
  6.  
  7. /* $VER: $Id: amiga.c,v 1.8 1995/08/11 12:13:49 tf Exp $ */
  8.  
  9. #include <exec/types.h>
  10. #include <exec/memory.h>
  11.  
  12. #include <intuition/intuition.h>
  13. #include <intuition/intuitionbase.h>
  14. #include <intuition/screens.h>
  15.  
  16. #include <graphics/gfx.h>
  17. #include <graphics/gfxbase.h>
  18. #include <graphics/view.h>
  19.  
  20. #include <stdio.h>
  21.  
  22. #include "astrolog.h"
  23. #include "rastport.h"
  24.  
  25. /*#define NOSCREEN*/
  26.     /* compile with -DNOSCREEN in order to get a window which opens on the Workbench screen
  27.      * and uses ObtainBestPen() to get it's colors.  (VERY UNSTABLE!) */
  28.  
  29. /* Prototypes */
  30.  
  31. extern ULONG AvailMem(ULONG);
  32. extern struct Screen *OpenScreenTagList( struct NewScreen *, struct TagItem * );
  33. extern struct Screen *LockPubScreen( UBYTE * );
  34. extern VOID UnlockPubScreen( UBYTE *, struct Screen * );
  35. extern VOID DrawImage( struct RastPort *, struct Image  *, WORD, WORD );
  36. extern struct TextFont *OpenDiskFont( struct TextAttr * );
  37. extern void CloseFont(struct TextFont *);
  38. extern void SetFont(struct RastPort *, struct TextFont *);
  39.  
  40. void StripIntuiMessages( struct MsgPort *mp, struct Window *win );
  41. void CloseWindowSafely( struct Window *win );
  42.  
  43. /*
  44. **  DATA
  45. */
  46.  
  47. #define NS_VIEWMODE  HIRES|LACE
  48. #define NS_TYPE      CUSTOMSCREEN|SCREENQUIET|AUTOSCROLL  /* V36+ ?! */
  49. #define NS_DEPTH     4  /* Bitplanes for 16 EGA colors */
  50.  
  51. #if defined(NOSCREEN)
  52. #define NW_FLAGS     WINDOWSIZING|RMBTRAP|REPORTMOUSE|NOCAREREFRESH|ACTIVATE|WINDOWCLOSE|WINDOWDRAG|WINDOWDEPTH
  53. #define NW_IDCMP     VANILLAKEY|MOUSEBUTTONS|MOUSEMOVE|NEWSIZE|INTUITICKS|CLOSEWINDOW
  54. #define NW_TYPE      WBENCHSCREEN
  55. #else /* !NOSCREEN */
  56. #define NW_FLAGS     BORDERLESS|WINDOWSIZING|RMBTRAP|REPORTMOUSE|NOCAREREFRESH|ACTIVATE/*|BACKDROP*/
  57. #define NW_IDCMP     VANILLAKEY|MOUSEBUTTONS|MOUSEMOVE|NEWSIZE|INTUITICKS/*|CLOSEWINDOW*/
  58. #define NW_TYPE      CUSTOMSCREEN
  59. #endif /* !NOSCREEN */
  60.  
  61. static UBYTE DisplayTitle[]= "Astrolog";
  62.  
  63. /*
  64.  *  Why the hell do people still use Kick1.3 ?
  65.  */
  66.  
  67. static struct NewScreen ns = {
  68.   0,0,               /* LeftEdge, TopEdge      */
  69.   724,480,           /* Width, Height          */
  70.   NS_DEPTH,          /* Depth (16 EGA Colors)  */
  71.   0,0,               /* DetailPen, BlockPen    */
  72.   NS_VIEWMODE,       /* ViewModes              */  /* <graphics/view.h> */
  73.   NS_TYPE,           /* Type                   */
  74.   NULL,              /* Font                   */
  75.   DisplayTitle,      /* DefaultTitle           */
  76.   NULL,              /* Gadgets                */
  77.   NULL,              /* CustomBitMap           */
  78. };
  79.  
  80. static struct NewWindow nw = {
  81.   0,0,               /* LeftEdge, TopEdge      */
  82.   724,480,           /* Width, Height          */
  83.   1,2,               /* DetailPen, BlockPen    */
  84.   NW_IDCMP,          /* IDCMP Flags            */
  85.   NW_FLAGS,          /* Flags                  */
  86.   NULL,              /* FirstGadget            */
  87.   NULL,              /* CheckMark              */
  88.   NULL,              /* Title                  */
  89.   NULL,              /* Screen                 */
  90.   NULL,              /* BitMap                 */
  91.   -1,-1,             /* MinWidth, MinHeight    */
  92.   -1,-1,             /* MaxWidth, MaxHeight    */
  93.   NW_TYPE,           /* Type                   */
  94. };
  95.  
  96. /* EGA color table */
  97.  
  98. static UWORD ega_rgb4[] = {
  99.  0x000, /* black      */
  100.  0xA00, /* maroon     */
  101.  0x0A0, /* dark green */
  102.  0xA60, /* orange     */
  103.  0x00A, /* dark blue  */
  104.  0xA0A, /* purple     */
  105.  0x0AA, /* dark cyan  */
  106.  0xBBB, /* light gray */
  107.  0x666, /* dark gray  */
  108.  0xF00, /* red        */
  109.  0x0F0, /* green      */
  110.  0xFF0, /* yellow     */
  111.  0x00F, /* blue       */
  112.  0xF0F, /* magenta    */
  113.  0x0FF, /* cyan       */
  114.  0xFFF, /* white      */
  115. };
  116.  
  117. /*
  118.  *  AmigaSetPen will use the EGA pen number as an index in the egapen[] array
  119.  *  in order to obtain the (best) corresponding Amiga pen.
  120.  *  If bestpen[p] is >= 0 then we have *allocated* this pen and have to release
  121.  *  it in AmigaDisplayExit().
  122.  */
  123.  
  124. static int egapen[16]  = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 };
  125. static int bestpen[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
  126.  
  127. struct IntuitionBase *IntuitionBase;
  128. struct GfxBase *GfxBase;
  129. ULONG *DiskfontBase= (ULONG *)0;
  130. LONG __stack = 8192;
  131.  
  132. /*
  133. **  32x32x4 icon image created from `astrolog.ico'
  134. */
  135.  
  136. static __chip const USHORT ico_data[] = {
  137.    0xe000, 0x0000,    /* ###............................. */
  138.    0xf800, 0x0000,    /* #####........................... */
  139.    0xfe20, 0x0000,    /* #######...#..................... */
  140.    0x6f00, 0x0004,    /* .##.####.....................#.. */
  141.    0x7380, 0x000e,    /* .###..###...................###. */
  142.    0x31cf, 0xf004,    /* ..##...###..########.........#.. */
  143.    0x38bf, 0xfc00,    /* ..###...#.############.......... */
  144.    0x1c7f, 0xfe00,    /* ...###...##############......... */
  145.    0x0eff, 0xff00,    /* ....###.################........ */
  146.    0x07ff, 0xff80,    /* .....####################....... */
  147.    0x07ff, 0xffc0,    /* .....#####################...... */
  148.    0x03ff, 0xffc0,    /* ......####################...... */
  149.    0x07ff, 0xffe0,    /* .....######################..... */
  150.    0x07ff, 0xffe0,    /* .....######################..... */
  151.    0x07ff, 0xffe0,    /* .....######################..... */
  152.    0x07ff, 0xffe0,    /* .....######################..... */
  153.    0x83ff, 0xffe0,    /* #.....#####################..... */
  154.    0x01ff, 0xffe0,    /* .......####################..... */
  155.    0x00ff, 0xffe0,    /* ........###################..... */
  156.    0x00ff, 0xffe0,    /* ........###################..... */
  157.    0x00ff, 0xffc0,    /* ........##################...... */
  158.    0x01ff, 0xffc0,    /* .......###################...... */
  159.    0x01ff, 0xffa2,    /* .......##################.#...#. */
  160.    0x00ff, 0xff70,    /* ........################.###.... */
  161.    0x207f, 0xfe38,    /* ..#......##############...###... */
  162.    0x503f, 0xff1c,    /* .#.#......##############...###.. */
  163.    0x200f, 0xf78c,    /* ..#.........########.####...##.. */
  164.    0x0000, 0x01ce,    /* .......................###..###. */
  165.    0x0000, 0x00f6,    /* ........................####.##. */
  166.    0x0002, 0x007f,    /* ..............#..........####### */
  167.    0x0000, 0x001f,    /* ...........................##### */
  168.    0x0000, 0x0007,    /* .............................### */
  169.  
  170.    0x0000, 0x0000,    /* ................................ */
  171.    0x0000, 0x0000,    /* ................................ */
  172.    0x0020, 0x0000,    /* ..........#..................... */
  173.    0x0000, 0x0004,    /* .............................#.. */
  174.    0x0000, 0x000e,    /* ............................###. */
  175.    0x000f, 0xf004,    /* ............########.........#.. */
  176.    0x003f, 0xfc00,    /* ..........############.......... */
  177.    0x007f, 0xfe00,    /* .........##############......... */
  178.    0x00ff, 0xff00,    /* ........################........ */
  179.    0x00ff, 0xff80,    /* ........#################....... */
  180.    0x00ff, 0xffc0,    /* ........##################...... */
  181.    0x007f, 0xffc0,    /* .........#################...... */
  182.    0x063f, 0xffe0,    /* .....##...#################..... */
  183.    0x071f, 0xffe0,    /* .....###...################..... */
  184.    0x079f, 0xffe0,    /* .....####..################..... */
  185.    0x078f, 0xffe0,    /* .....####...###############..... */
  186.    0x83c7, 0xffe0,    /* #.....####...##############..... */
  187.    0x1de3, 0xffe0,    /* ...###.####...#############..... */
  188.    0x3ef1, 0xffe0,    /* ..#####.####...############..... */
  189.    0x3ef8, 0xffe0,    /* ..#####.#####...###########..... */
  190.    0x3efc, 0x7fc0,    /* ..#####.######...#########...... */
  191.    0x1dfe, 0x1fc0,    /* ...###.########....#######...... */
  192.    0x01ff, 0x0f82,    /* .......#########....#####.....#. */
  193.    0x00ff, 0xc700,    /* ........##########...###........ */
  194.    0x207f, 0xe000,    /* ..#......##########............. */
  195.    0x503f, 0xf000,    /* .#.#......##########............ */
  196.    0x200f, 0xf000,    /* ..#.........########............ */
  197.    0x0000, 0x0000,    /* ................................ */
  198.    0x0000, 0x0000,    /* ................................ */
  199.    0x0002, 0x0000,    /* ..............#................. */
  200.    0x0000, 0x0000,    /* ................................ */
  201.    0x0000, 0x0000,    /* ................................ */
  202.  
  203.    0x0000, 0x0000,    /* ................................ */
  204.    0x0000, 0x0000,    /* ................................ */
  205.    0x0020, 0x0000,    /* ..........#..................... */
  206.    0x0000, 0x0004,    /* .............................#.. */
  207.    0x0000, 0x000e,    /* ............................###. */
  208.    0x0000, 0x0004,    /* .............................#.. */
  209.    0x0000, 0x0000,    /* ................................ */
  210.    0x0000, 0x0000,    /* ................................ */
  211.    0x0000, 0x003c,    /* ..........................####.. */
  212.    0x0000, 0x003e,    /* ..........................#####. */
  213.    0x0000, 0x001e,    /* ...........................####. */
  214.    0x0000, 0x005e,    /* .........................#.####. */
  215.    0x0000, 0x012e,    /* .......................#..#.###. */
  216.    0x0000, 0x004c,    /* .........................#..##.. */
  217.    0x0000, 0x00a0,    /* ........................#.#..... */
  218.    0x0000, 0x0040,    /* .........................#...... */
  219.    0x8000, 0x0120,    /* #......................#..#..... */
  220.    0x1c00, 0x0040,    /* ...###...................#...... */
  221.    0x3e00, 0x00a0,    /* ..#####.................#.#..... */
  222.    0x3e00, 0x0040,    /* ..#####..................#...... */
  223.    0x3e00, 0x0100,    /* ..#####................#........ */
  224.    0x1c00, 0x0000,    /* ...###.......................... */
  225.    0x0000, 0x0002,    /* ..............................#. */
  226.    0x0000, 0x0000,    /* ................................ */
  227.    0x2000, 0x0000,    /* ..#............................. */
  228.    0x5000, 0x0000,    /* .#.#............................ */
  229.    0x2000, 0x0000,    /* ..#............................. */
  230.    0x0000, 0x0000,    /* ................................ */
  231.    0x0000, 0x0000,    /* ................................ */
  232.    0x0002, 0x0000,    /* ..............#................. */
  233.    0x0000, 0x0000,    /* ................................ */
  234.    0x0000, 0x0000,    /* ................................ */
  235.  
  236.    0x6000, 0x0040,    /* .##......................#...... */
  237.    0xf000, 0x4000,    /* ####.............#.............. */
  238.    0xdc20, 0x0000,    /* ##.###....#..................... */
  239.    0x6900, 0x0200,    /* .##.#..#..............#......... */
  240.    0x3200, 0x0000,    /* ..##..#......................... */
  241.    0x3009, 0x5000,    /* ..##........#..#.#.#............ */
  242.    0x1802, 0xbc00,    /* ...##.........#.#.####.......... */
  243.    0x1c15, 0x6e00,    /* ...###.....#.#.#.##.###......... */
  244.    0x0e02, 0xbf0c,    /* ....###.......#.#.######....##.. */
  245.    0x0729, 0x5f86,    /* .....###..#.#..#.#.######....##. */
  246.    0x0702, 0xbfce,    /* .....###......#.#.########..###. */
  247.    0x0395, 0x6fc6,    /* ......###..#.#.#.##.######...##. */
  248.    0x01c2, 0xbfee,    /* .......###....#.#.#########.###. */
  249.    0x00e9, 0x57e4,    /* ........###.#..#.#.#.######..#.. */
  250.    0x0062, 0xbfe0,    /* .........##...#.#.#########..... */
  251.    0x0075, 0x6fe0,    /* .........###.#.#.##.#######..... */
  252.    0x803a, 0xbfe0,    /* #.........###.#.#.#########..... */
  253.    0x0c1d, 0x5fe0,    /* ....##.....###.#.#.########..... */
  254.    0x060e, 0xbfe1,    /* .....##.....###.#.#########....# */
  255.    0x0e07, 0x7fe0,    /* ....###......###.##########..... */
  256.    0x0643, 0xb7c0,    /* .....##..#....###.##.#####...... */
  257.    0x0c15, 0xffc0,    /* ....##.....#.#.###########...... */
  258.    0x0002, 0xffa2,    /* ..............#.#########.#...#. */
  259.    0x0029, 0x7f70,    /* ..........#.#..#.#######.###.... */
  260.    0x0002, 0xbe38,    /* ..............#.#.#####...###... */
  261.    0x2015, 0x5f18,    /* ..#........#.#.#.#.#####...##... */
  262.    0x0002, 0xb78c,    /* ..............#.#.##.####...##.. */
  263.    0x0080, 0x01cc,    /* ........#..............###..##.. */
  264.    0x0000, 0x00f6,    /* ........................####.##. */
  265.    0x0000, 0x003b,    /* ..........................###.## */
  266.    0x0000, 0x020f,    /* ......................#.....#### */
  267.    0x0800, 0x0006,    /* ....#........................##. */
  268. };
  269.  
  270.  
  271. static struct Image ico = {
  272.   0,                 /* LeftEdge   */
  273.   0,                 /* TopEdge    */
  274.   32,                /* Width      */
  275.   32,                /* Height     */
  276.   4,                 /* Depth      */
  277.   &ico_data[0],      /* ImageData  */
  278.   0x0F,              /* PlanePick  */
  279.   0x00,              /* PlaneOnOff */
  280.   NULL               /* NextImage  */
  281. };
  282.  
  283. extern struct Image icon_image;  /* xscreen.c */
  284.  
  285. /*
  286. **  CODE
  287. */
  288.  
  289. #define ERR_NO_INTITION 1
  290. #define ERR_NO_GRAPHICS 2
  291. #define ERR_NO_SCREEN   3
  292. #define ERR_NO_WINDOW   4
  293.  
  294. /* 
  295.  *  These variables are used to save those settings which might
  296.  *  get modified via AmigaDisplayInit().  They are restored by
  297.  *  AmigaDisplayExit()
  298.  */
  299.  
  300. static int gs_xWin, gs_yWin, gi_xOffset, gi_yOffset, us_fAnsi;
  301.  
  302. /****** amiga/AmigaDisplayInit ***********************************************
  303. *
  304. *   NAME
  305. *       AmigaDisplayInit -- Initialize an Amiga screen for Astrolog charts
  306. *
  307. *   SYNOPSIS
  308. *       error= AmigaDisplayInit();
  309. *
  310. *       int AmigaDisplayInit(void);
  311. *
  312. *   FUNCTION
  313. *       This function opens an Amiga screen with an EGA palette and a sizable
  314. *       window which is large enough to hold `gs.xWin' pixel columns and
  315. *       `gs.yWin' pixel rows.  If this should fail for any reason, an error
  316. *       code != 0 is returned.
  317. *
  318. *   INPUTS
  319. *       none
  320. *
  321. *   RESULT
  322. *       error - != 0 in case of an error,  0 otherwise
  323. *
  324. *   EXAMPLE
  325. *       #include "astrolog.h"
  326. *
  327. *       \* ... *\
  328. *
  329. *       if( AmigaDisplayInit() == 0 )
  330. *       {
  331. *          \* do some gfx... *\
  332. *
  333. *          AmigaDisplayExit();
  334. *       }
  335. *       else error();
  336. *
  337. *   NOTES
  338. *       Hack: The EGA colors provided for the screen are taken from the 
  339. *       global rgbbmp[] array (see xdata.c).  However, if the `us.fAnsi' flag 
  340. *       is set, a slightly brighter palette is used.
  341. *
  342. *       Note also that this function sets `us.fAnsi' to `fFalse' to make sure
  343. *       that no ANSI characters are used in the graphic chart mode.  The
  344. *       initial value of `us.fAnsi' is resored by AmigaDisplayExit().
  345. *
  346. *   BUGS
  347. *
  348. *   SEE ALSO
  349. *       AmigaDisplayExit()
  350. *
  351. ******************************************************************************
  352. *
  353. *  #define SPREAD(v) ((ULONG)(v)<<24 | (ULONG)(v)<<16 | (ULONG)(v)<<8 | (v))
  354. *
  355. *  SetRGB32(vp,0,SPREAD(255),SPREAD(255),SPREAD(255));
  356. *
  357. */
  358.  
  359.  
  360. /* scale an RGB4 fraction to RGB32 */
  361.  
  362. static long scale_rgb4(short v4)
  363. {
  364.   long v32= 0;
  365.   int i;
  366.  
  367.   for(i=0; i<8; i++)
  368.     v32 = (v32<<4) | v4;
  369.  
  370.   return v32;
  371. }
  372.  
  373. int AmigaDisplayInit()
  374. {
  375.   struct Screen *s;
  376.   struct Window *w;
  377.  
  378.   int err= 0;
  379.  
  380.   /* save initial values */
  381.  
  382.   gs_xWin = gs.xWin;    gi_xOffset = gi.xOffset;
  383.   gs_yWin = gs.yWin;    gi_yOffset = gi.yOffset;
  384.  
  385.   /* Astrolog problem:  Ansi characters not defined in the internal vector font */
  386.  
  387.   us_fAnsi = us.fAnsi;  us.fAnsi = fFalse;
  388.  
  389.   /*printf("AmigaDisplayInit() requested display geometry: %dx%d\n",gs.xWin,gs.yWin);*/
  390.  
  391.   if( (IntuitionBase= (struct IntuitionBase *)OpenLibrary("intuition.library",0L)) )
  392.   {
  393.     if( (GfxBase= (struct GfxBase *)OpenLibrary("graphics.library",0L)) )
  394.     {
  395.       /*
  396.        *  Die beiden printf()s zeigen, daß man hier eins addieren muß um am Ende
  397.        *  die tatsächlich gewünschte größe zu erhalten...
  398.        */
  399.  
  400.       ns.Width  = nw.Width  = gs.xWin +1;
  401.       ns.Height = nw.Height = gs.yWin +1;
  402.  
  403.       nw.MaxWidth = BITMAPX;      nw.MaxHeight = BITMAPY;
  404.       nw.MinWidth = BITMAPX1;     nw.MinHeight = BITMAPY1;
  405.  
  406. #if !defined(NOSCREEN)
  407.       /*
  408.       **  Should we better try to clone the Workbench screen?
  409.       */
  410.  
  411.       if (IntuitionBase->LibNode.lib_Version <= 34)
  412.         s= (struct Screen *)OpenScreen(&ns);
  413.  
  414.       else /* Kickstart 2.0+ */
  415.       {
  416.         static struct TagItem scrtaglist[] = { {SA_Overscan,OSCAN_TEXT},{TAG_DONE,0} };
  417.  
  418.         /*ns.Width  = STDSCREENWIDTH;*/
  419.         /*ns.Height = STDSCREENHEIGHT;*/
  420.  
  421.         s= OpenScreenTagList(&ns,scrtaglist);
  422.       }
  423.  
  424.       if(s)
  425.       {
  426.         if(us_fAnsi == fFalse) /* hack! */
  427.         {
  428.           /* create a new colormap from `xdata.c' which is slightly darker than the one above */
  429.  
  430.           int i;
  431.           for(i=0; i<(1<<ns.Depth); i++)
  432.           {
  433.             UWORD r=  (rgbbmp[i] & 0x0000FF)         / 0x10;
  434.             UWORD g= ((rgbbmp[i] & 0x00FF00) >>  8)  / 0x10;
  435.             UWORD b= ((rgbbmp[i] & 0xFF0000) >> 16)  / 0x10;
  436.  
  437.             ega_rgb4[i]= (r<<8) | (g<<4) | b;
  438.             /*printf("ega_rgb4[%d] = 0x%03x\n",i,ega_rgb4[i]);*/
  439.           }
  440.         }
  441.  
  442.         ShowTitle(s,FALSE);
  443.         LoadRGB4(&s->ViewPort, ega_rgb4, 1<<(ns.Depth));
  444.         nw.Screen= s;
  445.  
  446. #else /* NOSCREEN */
  447.       if(1)
  448.       {
  449.         nw.Screen = (struct Screen *)0;
  450.         nw.Type   = WBENCHSCREEN;
  451.         nw.Title  = /*ns.DefaultTitle*/ DisplayTitle;
  452.  
  453.         s= LockPubScreen( NULL );
  454. #endif /* NOSCREEN */
  455.  
  456.         if(nw.Width  > s->Width)   nw.Width  = s->Width;
  457.         if(nw.Height > s->Height)  nw.Height = s->Height;
  458.  
  459.         if( (w= (struct Window *)OpenWindow(&nw)) )
  460.         {
  461.           int xmin= (int)(w->BorderLeft);
  462.           int ymin= (int)(w->BorderTop);
  463.           int xmax= (int)(w->Width  - w->BorderRight  - 1);
  464.           int ymax= (int)(w->Height - w->BorderBottom - 1);
  465.  
  466.           gi.xOffset = xmin;
  467.           gi.yOffset = ymin;
  468.  
  469.           gs.xWin = xmax - xmin;
  470.           gs.yWin = ymax - ymin;
  471.  
  472. #if defined(NOSCREEN)
  473.           UnlockPubScreen( NULL, s );
  474.           s= w->WScreen;
  475. #endif /* NOSCREEN */
  476.  
  477.           gi.scr = s;
  478.           gi.win = w;
  479.           gi.rp  = w->RPort;  gi.paging = 0;  /* <-- */
  480.  
  481.           /*printf("AmigaDisplayInit() allocated display geometry: %dx%d\n",gs.xWin,gs.yWin);*/
  482.  
  483. #if !defined(NOSCREEN)
  484.           /*
  485.           **  SetRast() können wir hier nur deshalb benutzen, weil wir die
  486.           **  Window Border sowieso nicht sehen wollen...
  487.           */
  488.  
  489.           SetRast(w->RPort, 0L);
  490.  
  491. #else /* NOSCREEN */
  492.           {
  493.             struct ColorMap *cm= w->WScreen->ViewPort.ColorMap;
  494.             int p;
  495.  
  496.             for(p=0; p<16; p++)
  497.             {
  498.               long r,g,b;
  499.  
  500.                r= scale_rgb4( (ega_rgb4[p] & 0x0F00) >> 8 );
  501.                g= scale_rgb4( (ega_rgb4[p] & 0x00F0) >> 4 );
  502.                b= scale_rgb4( (ega_rgb4[p] & 0x000F)      );
  503.  
  504.                bestpen[p]= ObtainBestPen( cm, r,g,b, OBP_Precision, PRECISION_GUI, TAG_END );
  505.  
  506.                if(bestpen[p] >= 0)
  507.                  egapen[p]= bestpen[p];
  508.             }
  509.           }
  510. #endif /* NOSCREEN */
  511.         }
  512.  
  513.         else /* OpenWindow() failed */
  514.         {
  515. #if !defined(NOSCREEN)
  516.           CloseScreen(s);
  517. #endif /* !NOSCREEN */
  518.           err= ERR_NO_WINDOW;
  519.         }
  520.       }
  521.       else /* OpenScreen() failed */
  522.         err= ERR_NO_SCREEN;
  523.     }
  524.   }
  525.  
  526.   return err;
  527. }
  528.  
  529. /****** amiga/AmigaDisplayPaging *********************************************
  530. *
  531. *   NAME
  532. *       AmigaDisplayPaging -- Allocate or free the page for animations
  533. *
  534. *   SYNOPSIS
  535. *       paging= AmigaDisplayPaging();
  536. *
  537. *       int AmigaDisplayPaging(void);
  538. *
  539. *   FUNCTION
  540. *       Here we allocate a 2nd rastport for double buffering.  All Amiga
  541. *       drawing happens in `gi.rp' and here we replace `gi.rp' with a newly
  542. *       allocated rastport which has the same size as the one of the astrolog
  543. *       screen `gi.scr'.  Since paging is mainly used for animation purposes, 
  544. *       we also add the INTUITICKS bit to our window's IDCMP port.
  545. *       Failure due to low memory is no fatal error because double buffering is
  546. *       only a bonus for the animations.
  547. *
  548. *   INPUTS
  549. *       none
  550. *
  551. *   RESULT
  552. *       paging - 0 if we disabled paging with this call, !=0 otherwise.
  553. *
  554. *   EXAMPLE
  555. *       #include "astrolog.h"
  556. *
  557. *       \* ... *\
  558. *
  559. *       if( AmigaDisplayInit() == 0 )
  560. *       {
  561. *         \* switch to double buffering mode *\
  562. *
  563. *         if(!gi.paging)
  564. *           AmigaDisplayPaging();
  565. *
  566. *         \* do some anim stuff... *\
  567. *
  568. *         AmigaDisplayExit();
  569. *       }
  570. *       else error();
  571. *
  572. *   NOTES
  573. *
  574. *   BUGS
  575. *
  576. *   SEE ALSO
  577. *       AmigaDisplayPaging(), AmigaDisplayExit()
  578. *
  579. ******************************************************************************
  580. *
  581. *
  582. */
  583.  
  584. int AmigaDisplayPaging(void)
  585. {
  586.   if(gi.paging)
  587.   {
  588.     rp_dispose(gi.rp);
  589.     gi.rp= (gi.win)->RPort;
  590.     gi.paging= 0;
  591.  
  592.     ModifyIDCMP(gi.win, (gi.win->IDCMPFlags) & ~INTUITICKS);
  593.   }
  594.   else /* !gi.paging */
  595.   {
  596.     struct RastPort *rp= rp_new(gi.scr->Width, gi.scr->Height, gi.scr->RastPort.BitMap->Depth);
  597.  
  598.     if(rp)
  599.     {
  600.       gi.rp= rp;
  601.       gi.paging= 1;
  602.  
  603.       ModifyIDCMP(gi.win, (gi.win->IDCMPFlags) | INTUITICKS);
  604.     }
  605.   }
  606.   return gi.paging;
  607. }
  608.  
  609.  
  610. /****** amiga/AmigaDisplayExit ***********************************************
  611. *
  612. *   NAME
  613. *       AmigaDisplayExit -- Dispose Astrolog's Amiga graphics stuff
  614. *
  615. *   SYNOPSIS
  616. *       AmigaDisplayExit();
  617. *
  618. *       void AmigaDisplayExit(void);
  619. *
  620. *   FUNCTION
  621. *       This function closes Astrolog's window and screen which had been
  622. *       provided via AmigaDisplayInit().  If paging is on, i.e. a 2nd
  623. *       page has been provided for animations, then this page is disposed
  624. *       as well.
  625. *
  626. *   INPUTS
  627. *       none
  628. *
  629. *   RESULT
  630. *       none
  631. *
  632. *   EXAMPLE
  633. *       #include "astrolog.h"
  634. *
  635. *       \* ... *\
  636. *
  637. *       if( AmigaDisplayInit() == 0 )
  638. *       {
  639. *          \* do some gfx... *\
  640. *
  641. *          AmigaDisplayExit();
  642. *       }
  643. *       else error();
  644. *
  645. *   NOTES
  646. *
  647. *   BUGS
  648. *
  649. *   SEE ALSO
  650. *       AmigaDisplayInit()
  651. *
  652. ******************************************************************************
  653. *
  654. *
  655. */
  656.  
  657. void AmigaDisplayExit()
  658. {
  659.   if(gi.paging)
  660.   {
  661.     AmigaDisplayPaging();
  662.   }
  663.  
  664. #if defined(NOSCREEN)
  665.   {
  666.     struct ColorMap *cm= (gi.win)->WScreen->ViewPort.ColorMap;
  667.     int p;
  668.  
  669.     for(p=0; p<16; p++)
  670.       if(bestpen[p] >= 0)
  671.         ReleasePen(cm,bestpen[p]);
  672.   }
  673. #endif /* NOSCREEN */
  674.  
  675.   if(gi.win)
  676.   {
  677.     /*CloseWindow(gi.win);*/
  678.     CloseWindowSafely(gi.win);
  679.     gi.win= (struct Window *)0;
  680.   }
  681.  
  682. #if !defined(NOSCREEN)
  683.   if(gi.scr)
  684.   {
  685.     CloseScreen(gi.scr);
  686.     gi.scr= (struct Screen *)0;
  687.   }
  688. #endif /* !NOSCREEN */
  689.  
  690.   if(GfxBase)
  691.   {
  692.     CloseLibrary((struct Library *)GfxBase);
  693.     GfxBase= (struct GfxBase *)0;
  694.   }
  695.  
  696.   if(IntuitionBase)
  697.   {
  698.     CloseLibrary((struct Library *)IntuitionBase);
  699.     IntuitionBase= (struct IntuitionBase *)0;
  700.   }
  701.  
  702.   /* restore initial values */
  703.  
  704.   gs.xWin = gs_xWin;    gi.xOffset = gi_xOffset;
  705.   gs.yWin = gs_yWin;    gi.yOffset = gi_yOffset;
  706.  
  707.   us.fAnsi = us_fAnsi;
  708. }
  709.  
  710. /****** amiga/AmigaDisplayUpdate *********************************************
  711. *
  712. *   NAME
  713. *       AmigaDisplayUpdate -- Display the temporary drawing page
  714. *
  715. *   SYNOPSIS
  716. *       AmigaDisplayUpdate();
  717. *
  718. *       void AmigaDisplayUpdate(void);
  719. *
  720. *   FUNCTION
  721. *       If double buffering is enabled, then the hidden page (which is the
  722. *       one we use to paint on) will be copied to the currently visible page.
  723. *       Without any 2nd page, calling this procedure is a no-op.
  724. *
  725. *   INPUTS
  726. *       none
  727. *
  728. *   RESULT
  729. *       none
  730. *
  731. *   EXAMPLE
  732. *
  733. *   NOTES
  734. *
  735. *   BUGS
  736. *
  737. *   SEE ALSO
  738. *       AmigaDisplayPaging()
  739. *
  740. ******************************************************************************
  741. *
  742. *
  743. */
  744.  
  745. void AmigaDisplayUpdate(void)
  746. {
  747.   if(gi.paging)
  748.     ClipBlit(gi.rp, 0,0, gi.win->RPort, 0,0, gi.win->Width,gi.win->Height, 0xc0);
  749. }
  750.  
  751.  
  752. /****** amiga/AmigaClearScreen ***********************************************
  753. *
  754. *   NAME
  755. *       AmigaClearScreen -- Clear Astrolog's Amiga graphics display
  756. *
  757. *   SYNOPSIS
  758. *       AmigaClearScreen();
  759. *
  760. *       void AmigaClearScreen(void);
  761. *
  762. *   FUNCTION
  763. *       This procedure unsets all pixels in the drawing page.
  764. *
  765. *   INPUTS
  766. *       none
  767. *
  768. *   RESULT
  769. *       none
  770. *
  771. *   EXAMPLE
  772. *
  773. *   NOTES
  774. *       Calling this function is usually faster than painting a rectangle
  775. *       covering the whole screen.
  776. *
  777. *   BUGS
  778. *
  779. *   SEE ALSO
  780. *       AmigaDisplayPaging()
  781. *
  782. ******************************************************************************
  783. *
  784. *
  785. */
  786.  
  787. void AmigaClearScreen(void)
  788. {
  789.  
  790. #if defined(NOSCREEN)
  791.   if(gi.win && gi.rp)
  792.   {
  793.     struct RastPort *rp= gi.rp;
  794.     struct Window *w= gi.win;
  795.  
  796.     SHORT xmin= (SHORT)(w->BorderLeft);
  797.     SHORT ymin= (SHORT)(w->BorderTop);
  798.     SHORT xmax= (SHORT)(w->Width  - w->BorderRight  - 1);
  799.     SHORT ymax= (SHORT)(w->Height - w->BorderBottom - 1);
  800.  
  801.     SetAPen(rp,0L);
  802.     RectFill(rp, xmin,ymin, xmax,ymax);
  803.   }
  804. #else /* !NOSCREEN */
  805.   SetRast(gi.rp,0L);
  806. #endif /* !NOSCREEN */
  807. }
  808.  
  809. /****** amiga/AmigaDisplayResize *********************************************
  810. *
  811. *   NAME
  812. *       AmigaDisplayResize -- Guarantee certain graphic display dimensions
  813. *
  814. *   SYNOPSIS
  815. *       error= AmigaDisplayResize(width, height);
  816. *
  817. *       int AmigaDisplayResize(int, int);
  818. *
  819. *   FUNCTION
  820. *       This function makes sure that the Amiga graphics page (screen and
  821. *       window) are large enough to hold a graphic with `width' pixels 
  822. *       horizontally and `height' pixels vertically.  If the current screen
  823. *       is large enough, nothing happens.  Otherwise it will be enlarged
  824. *       to the given size.
  825. *
  826. *   INPUTS
  827. *       none
  828. *
  829. *   RESULT
  830. *       error - != 0 in case of an error,  0 otherwise
  831. *
  832. *   EXAMPLE
  833. *
  834. *   NOTES
  835. *
  836. *   BUGS
  837. *
  838. *   SEE ALSO
  839. *       AmigaDisplayInit(), AmigaDisplayExit()
  840. *
  841. ******************************************************************************
  842. *
  843. *
  844. */
  845.  
  846. int AmigaDisplayResize(int width, int height)
  847. {
  848.   int err= 0;
  849.  
  850.   /* We only have to close screen and window if we must enlarge the display */
  851.  
  852.   if( (width > (gi.win)->Width) || (height > (gi.win)->Height) )
  853.   {
  854.     int p= gi.paging;
  855.  
  856.     AmigaDisplayExit();
  857.  
  858.     if(width  > gs.xWin)  gs.xWin= width;
  859.     if(height > gs.yWin)  gs.yWin= height;
  860.  
  861.     err= AmigaDisplayInit();
  862.  
  863.     if(!err && p)
  864.       AmigaDisplayPaging();
  865.   }
  866.  
  867.   /*
  868.   **  Now that we can be sure that the display is large enough, we fake
  869.   **  the exact desired dimensions
  870.   */
  871.  
  872.   gs.xWin= width;
  873.   gs.yWin= height;
  874.  
  875.   return err;
  876. }
  877.  
  878. /****** amiga/AmigaGetKey ****************************************************
  879. *
  880. *   NAME
  881. *       AmigaGetKey -- Wait for a keypress and return it's ASCII code
  882. *
  883. *   SYNOPSIS
  884. *       key= AmigaGetKey();
  885. *
  886. *       int AmigaGetKey(void);
  887. *
  888. *   FUNCTION
  889. *       Wait for a keypress and return the ASCII code of that key.  This 
  890. *       function distinguishes between console mode and graphics mode and
  891. *       calls getkey() if there is no graphics window.
  892. *
  893. *   INPUTS
  894. *       none
  895. *
  896. *   RESULT
  897. *       key   - The ASCII code of the character on the pressed key
  898. *
  899. *   EXAMPLE
  900. *
  901. *   NOTES
  902. *
  903. *   BUGS
  904. *
  905. *   SEE ALSO
  906. *       getkey()
  907. *
  908. ******************************************************************************
  909. *
  910. *
  911. */
  912.  
  913. int AmigaGetKey(void)
  914. {
  915.   int key= '\0';
  916.  
  917.   if(gi.win)
  918.   {
  919.     struct Window *w= gi.win;
  920.  
  921.     while(!key)
  922.     {
  923.       ULONG sig= Wait( SIGBREAKF_CTRL_C | (1L<<w->UserPort->mp_SigBit) );
  924.  
  925.       if( sig & SIGBREAKF_CTRL_C )
  926.         key= '\003';
  927.  
  928.       if( sig & (1L<<w->UserPort->mp_SigBit) )
  929.       {
  930.         struct IntuiMessage *imsg;
  931.  
  932.         while( (imsg=(struct IntuiMessage *)GetMsg(w->UserPort)) )
  933.         {
  934.           ULONG  class  = imsg->Class;
  935.           USHORT code   = imsg->Code;
  936.  
  937.           ReplyMsg((struct Message *)imsg);
  938.  
  939.           switch(class)
  940.           {
  941.             case VANILLAKEY:
  942.               key= (int)code;
  943.               break;
  944.           }
  945.         }
  946.       }
  947.     }
  948.   }
  949.   else /* !gi.win */
  950.     key= getkey();
  951.  
  952.   return key;
  953. }
  954.  
  955.  
  956. /*
  957. **  undocumented hacks...
  958. */
  959.  
  960. void AmigaSetPen(int pen) { SetAPen(gi.rp,egapen[pen]); }
  961.  
  962. int AmigaMaxDisplayRows(void)
  963. {
  964.   int result= 2730;
  965.  
  966.   if(gi.scr)
  967.   {
  968.     result= (gi.scr)->Height;
  969.   }
  970.  
  971.   else /* !gi.scr */
  972.   {
  973.     if(IntuitionBase)
  974.     {
  975.       struct Screen *s= LockPubScreen( NULL );
  976.  
  977.       if(s)
  978.         result= s->Height;
  979.  
  980.       UnlockPubScreen( NULL, s );
  981.     }
  982.   }
  983.  
  984.   return result;
  985. }
  986.  
  987.  
  988. int AmigaMaxDisplayColumns(void)
  989. {
  990.   int result= 2730;
  991.  
  992.   if(gi.scr)
  993.   {
  994.     result= (gi.scr)->Width;
  995.   }
  996.  
  997.   else /* !gi.scr */
  998.   {
  999.     if(IntuitionBase)
  1000.     {
  1001.       struct Screen *s= LockPubScreen( NULL );
  1002.  
  1003.       if(s)
  1004.         result= s->Width;
  1005.  
  1006.       UnlockPubScreen( NULL, s );
  1007.     }
  1008.   }
  1009.  
  1010.   return result;
  1011. }
  1012.  
  1013.  
  1014.  
  1015. char *AmigaGetString(char *buf)
  1016. {
  1017.   int key, n=0;
  1018.  
  1019.   do
  1020.   {
  1021.     key= AmigaGetKey();
  1022.  
  1023.     if(32 <= key && key <= 127)
  1024.     {
  1025.       buf[n++]= key;
  1026.       xPrint("%c",key);
  1027.     }
  1028.  
  1029.     else if(key=='\b')
  1030.     {
  1031.       if(n>0)
  1032.       {
  1033.         int pen= gi.kiCur;
  1034.  
  1035.         --n;
  1036.  
  1037.         DrawColor(gi.kiOff);
  1038.         xPrint("\b%c\b",buf[n]);
  1039.         DrawColor(pen);
  1040.       }
  1041.       else DisplayBeep(gi.scr);
  1042.     }
  1043.  
  1044.     else if(key=='\n' || key=='\r')
  1045.     {
  1046.       buf[n]= '\0';
  1047.     }
  1048.     else DisplayBeep(gi.scr);
  1049.  
  1050.   } while(key!='\n' && key!='\r');
  1051.  
  1052.   return buf;
  1053. }
  1054.  
  1055.  
  1056. /**/
  1057.  
  1058. int AmigaDisplayDebug(void)
  1059. {
  1060.   AmigaClearScreen();
  1061.   DrawImage(gi.rp, &ico, gs.xWin-ico.Width, 0);
  1062.   /*DrawImage(gi.rp, &icon_image, gs.xWin-icon_image.Width,100);*/
  1063.  
  1064.   xPrintAt(1,1,"");
  1065.  
  1066.   /*
  1067.    *  Who is the first to blame me for this abuse of the `-k' switch (-;
  1068.    */
  1069.  
  1070.   if(us_fAnsi)
  1071.   {
  1072.     DiskfontBase= (struct DiskfontBase *)OpenLibrary("diskfont.library",0L);
  1073.  
  1074.     if(DiskfontBase)
  1075.     {
  1076.       static struct TextAttr ta = { "CGTimes.font", 70, FS_NORMAL, FPF_DISKFONT };
  1077.       struct TextFont *tf;
  1078.  
  1079.       xPrintAt(1,1,"{green}Computing `{white}%s{green}' ({white}%d{green}) ... Please Wait ...",ta.ta_Name,ta.ta_YSize);
  1080.  
  1081.       if( (tf= OpenDiskFont(&ta)) )
  1082.       {
  1083.         struct RastPort *rp= gi.rp;
  1084.         char *str= "Astrolog";
  1085.         int L= strlen(str);
  1086.         int l,x,y;
  1087.  
  1088.         xPrintAt(1,1,"{black}Computing `%s' (%d) ... Please Wait ...",ta.ta_Name,ta.ta_YSize);
  1089.  
  1090.         DrawImage(rp, &ico, 0,0);
  1091.         DrawImage(rp, &ico, gs.xWin-ico.Width, 0);
  1092.  
  1093.         SetFont(rp,tf);
  1094.  
  1095.         l= TextLength(rp,str,L);
  1096.         x= (gs.xWin-l)/2;
  1097.         y= tf->tf_Baseline+1;
  1098.  
  1099.         /* smoothing via outline */
  1100.  
  1101.         DrawColor(kLtGray);  SetDrMd(gi.rp,JAM1);
  1102.         /*Move(rp, x-1,y-1); Text(rp,str,L);*/
  1103.         Move(rp, x  ,y-1); Text(rp,str,L);
  1104.         Move(rp, x+1,y-1); Text(rp,str,L);
  1105.         Move(rp, x-1,y  ); Text(rp,str,L);
  1106.         Move(rp, x+1,y  ); Text(rp,str,L);
  1107.         Move(rp, x-1,y+1); Text(rp,str,L);
  1108.         Move(rp, x  ,y+1); Text(rp,str,L);
  1109.         /*Move(rp, x+1,y+1); Text(gi.rp,str,L);*/
  1110.  
  1111.         DrawColor(kWhite);
  1112.         Move(gi.rp, x,y);
  1113.         Text(gi.rp,str,L);
  1114.  
  1115.         DrawColor(kRed);
  1116.         DrawLine(0,tf->tf_YSize+5, gs.xWin,tf->tf_YSize+5);
  1117.  
  1118.         CloseFont(tf);
  1119.  
  1120.         xPrintAt(9,1,"");
  1121.       }
  1122.       else
  1123.         xPrint(" {red}failed.\n\n");
  1124.  
  1125.       CloseLibrary(DiskfontBase);
  1126.     }
  1127.     else xPrintAt(1,1,"{red}Warning: could not open {white}diskfont.library{red}!\n");
  1128.   }
  1129.  
  1130.   xPrint("{white}** %s version %s **\n", szAppName, szVersionCore);
  1131.   xPrint("{ltgray}As of %s  (compiled %s, %s)\n", szDateCore, __DATE__, __TIME__);
  1132.   xPrint("{cyan}By Walter D. Pullen (%s)\n", szAddressCore);
  1133.   xPrint("{yellow}Amiga port by Tobias Ferber (tf@antares.ping.de)\n");
  1134.  
  1135.   xPutString("\n\n");
  1136.  
  1137.   {
  1138.     /* Graphics chart modes */
  1139.  
  1140.     static char *gcm[] = {
  1141.       "<unknown>",   /*  0 */
  1142.       "gWheel",      /*  1 */
  1143.       "gHouse",      /*  2 */
  1144.       "gGrid",       /*  3 */
  1145.       "gHorizon",    /*  4 */
  1146.       "gOrbit",      /*  5 */
  1147.       "gAstroGraph", /*  6 */
  1148.       "gEphemeris",  /*  7 */
  1149.       "gWorldMap",   /*  8 */
  1150.       "gGlobe",      /*  9 */
  1151.       "gPolar",      /* 10 */
  1152.       "gBiorhythm",  /* 11 */
  1153.       "gCalendar",   /* 12 */
  1154.       "gDisposit",   /* 13 */
  1155.     };
  1156.  
  1157.     xPrint("{red}Internal settings page called from graphic chart mode {white}%d{red} ({white}%s{red})\n",
  1158.       gi.nMode, gcm[gi.nMode]);
  1159.   }
  1160.  
  1161.   xPutString("\n");
  1162.  
  1163.   {
  1164.     struct Window *w= gi.win;
  1165.  
  1166.     xPrint("{green}Current window geometry: {white}%d{green}x{white}%d{green}x{white}%d"
  1167.            "{green}, borders (left,top,right,bottom): {white}%d{green},{white}%d{green},{white}%d{green},{white}%d\n",
  1168.       w->Width, w->Height, w->RPort->BitMap->Depth,
  1169.       w->BorderLeft, w->BorderTop, w->BorderRight, w->BorderBottom);
  1170.  
  1171.     xPrint("{green}Resulting maximum playfield: ({white}%d{green},{white}%d{green}) .. ({white}%d{green},{white}%d{green}) [geometry {white}%d{green}x{white}%d{green}]\n",
  1172.       w->BorderLeft,
  1173.       w->BorderTop,
  1174.       w->Width  - w->BorderRight  - 1,
  1175.       w->Height - w->BorderBottom - 1,
  1176.       w->Width  - w->BorderRight  - 1 - w->BorderLeft,
  1177.       w->Height - w->BorderBottom - 1 - w->BorderTop);
  1178.  
  1179.     xPrint("{green}Actually used playfield: ({white}%d{green},{white}%d{green}) .. ({white}%d{green},{white}%d{green})  [geometry {white}%d{green}x{white}%d{green}]\n",
  1180.       gi.xOffset,gi.yOffset, gs.xWin,gs.yWin,gs.xWin-gi.xOffset,gs.yWin-gi.yOffset);
  1181.  
  1182.     xPrint("{green}Paging is {white}%s{green} for animation mode {white}%d{green}.\n",
  1183.       gi.paging ? "enabled" : "disabled", gs.nAnim);
  1184.   }
  1185.  
  1186.   xPutString("\n");
  1187.  
  1188.   {
  1189.     xPrint("{green}"
  1190.            "EGA Colors: "  "{black}"     "black,   "
  1191.                            "{maroon}"    "maroon,  "
  1192.                            "{dkgreen}"   "dkgreen, "
  1193.                            "{orange}"    "orange,  "
  1194.                            "{dkblue}"    "dkblue,  "
  1195.                            "{purple}"    "purple,  "
  1196.                            "{dkcyan}"    "dkcyan,  "
  1197.                            "{ltgray}"    "ltgray,  "  "\n"
  1198.            "            "  "{dkgray}"    "dkgray,  "
  1199.                            "{red}"       "red,     "
  1200.                            "{green}"     "green,   "
  1201.                            "{yellow}"    "yellow,  "
  1202.                            "{blue}"      "blue,    "
  1203.                            "{magenta}"   "magenta, "
  1204.                            "{cyan}"      "cyan,    "
  1205.                            "{white}"     "white.   "  "\n");
  1206.   }
  1207.  
  1208.   xPutString("\n");
  1209.  
  1210.   {
  1211.     ULONG chip= AvailMem(MEMF_CHIP);
  1212.     ULONG fast= AvailMem(MEMF_FAST);
  1213.  
  1214.     xPrint("{cyan}Available memory: {white}%ld{cyan} bytes (CHIP: {white}%ld{cyan}, FAST: {white}%ld{cyan})\n",
  1215.       chip,fast,chip+fast);
  1216.  
  1217.     chip= AvailMem(MEMF_CHIP|MEMF_LARGEST);
  1218.     fast= AvailMem(MEMF_FAST|MEMF_LARGEST);
  1219.  
  1220.     xPrint("{cyan}Largest available memory block: {white}%ld{cyan} bytes CHIP, {white}%ld{cyan} bytes FAST.\n",
  1221.       chip,fast);                                         
  1222.   }
  1223.  
  1224.   xPutString("\n");
  1225.  
  1226.   if(!gi.paging)
  1227.   {
  1228.     /*
  1229.     **  Taken from CommandLineX()
  1230.     */
  1231.  
  1232.     char szCommandLine[cchSzMax], *rgsz[MAXSWITCHES];
  1233.     int argc, fT;
  1234.  
  1235.     ciCore = ciMain;
  1236.     fT = us.fLoop; us.fLoop = fTrue;
  1237.     argc = NPromptSwitches(szCommandLine, rgsz);
  1238.     is.cchRow = 0;
  1239.     is.fSzInteract = fTrue;
  1240.  
  1241.     if( FProcessSwitches(argc, rgsz) )
  1242.     {
  1243.       is.fMult = fFalse;
  1244.       FPrintTables();
  1245.  
  1246.       if (is.fMult)
  1247.       {
  1248.         ClearB((lpbyte)&us.fCredit, (int)((lpbyte)&us.fLoop - (lpbyte)&us.fCredit));
  1249.       }
  1250.     }
  1251.  
  1252.     is.fSzInteract = fFalse;
  1253.     us.fLoop = fT;
  1254.     ciMain = ciCore;
  1255.   }
  1256.  
  1257.   xPutString("{magenta}Press any key to continue (or any other to resume) ...");
  1258.   AmigaDisplayUpdate();
  1259.   return AmigaGetKey();
  1260. }
  1261.  
  1262. /* Generic NDK Code */
  1263.  
  1264. #include "exec/types.h"
  1265. #include "exec/nodes.h"
  1266. #include "exec/lists.h"
  1267. #include "exec/ports.h"
  1268. #include "intuition/intuition.h"
  1269.  
  1270. /*
  1271.  * Remove and reply all IntuiMessages on a port that have been sent to a particular window
  1272.  * ( note that we don't rely on the ln_Succ pointer of a message after we have replied it )
  1273.  */
  1274.  
  1275. void
  1276. StripIntuiMessages( mp, win )
  1277. struct MsgPort *mp;
  1278. struct Window *win;
  1279. {
  1280.   struct IntuiMessage *msg;
  1281.   struct Node *succ;
  1282.  
  1283.   msg= (struct IntuiMessage *)mp->mp_MsgList.lh_Head;
  1284.  
  1285.   while( (succ= msg->ExecMessage.mn_Node.ln_Succ) )
  1286.   {
  1287.     if( msg->IDCMPWindow ==  win )
  1288.     {
  1289.       /* Intuition is about to free this message.
  1290.        * Make sure that we have politely sent it back.
  1291.        */
  1292.       Remove( (struct Node *)msg );
  1293.       ReplyMsg( (struct Message *)msg );
  1294.     }
  1295.  
  1296.     msg= (struct IntuiMessage *)succ;
  1297.   }
  1298. }
  1299.  
  1300. /*
  1301.  * These functions close an Intuition window that shares a port with other Intuition
  1302.  * windows or IPC customers.
  1303.  *
  1304.  * We are careful to set the UserPort to null before closing, and to free
  1305.  * any messages that it might have been sent.
  1306.  */
  1307.  
  1308. void
  1309. CloseWindowSafely( struct Window *win )
  1310. {
  1311.   /* we forbid here to keep out of race conditions with Intuition */
  1312.   Forbid();
  1313.  
  1314.   /* send back any messages for this window
  1315.    * that have not yet been processed
  1316.    */
  1317.   StripIntuiMessages( win->UserPort, win );
  1318.  
  1319.   /* tell Intuition to stop sending more messages */
  1320.   ModifyIDCMP( win, 0L );
  1321.  
  1322.   /* turn multitasking back on */
  1323.   Permit();
  1324.  
  1325.   /* and really close the window */
  1326.   CloseWindow( win );
  1327. }
  1328.